package com.fafu.rbac.security.filter;

import com.fafu.common.redis.utils.ByteRedisUtil;
import com.fafu.rbac.security.bean.WegoUserDetails;
import com.fafu.rbac.security.utils.JwtUtil;
import io.jsonwebtoken.Claims;
import org.springframework.security.authentication.InsufficientAuthenticationException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;
import org.springframework.web.filter.OncePerRequestFilter;

import javax.annotation.Resource;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.nio.file.AccessDeniedException;

@Component
public class JwtAuthenticationFilter extends OncePerRequestFilter {

    @Resource
    private ByteRedisUtil<WegoUserDetails> wegoUserDetailsByteRedisUtil;

    @Resource
    private JwtUtil jwtUtil;

    @Override
    protected void doFilterInternal(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, FilterChain filterChain) throws ServletException, IOException {
        //1、获取用户请求时传递过来的token
        String token = httpServletRequest.getHeader("Authorization");
        if(token == null || token.length() == 0){
            //放行到过滤器链中的下一个过滤器过滤
            filterChain.doFilter(httpServletRequest,httpServletResponse);
            return;
        }
        //如果用户请求携带有token，解析token
        Claims claimsFromToken = null;
        try {
            claimsFromToken = jwtUtil.getClaimsFromToken(token);
        } catch (Exception e) {
            e.printStackTrace();
            throw new  InsufficientAuthenticationException("非法的token");
        }
        //获取用户id
        String userId = claimsFromToken.getSubject();

        //从Redis中获取缓存的用户数据
        WegoUserDetails wegoUserDetails = null;
        try {
            wegoUserDetails = wegoUserDetailsByteRedisUtil.get("user:" + userId);
        } catch (Exception e) {
            e.printStackTrace();
            throw new  InsufficientAuthenticationException("无效的token");
        }
        if(wegoUserDetails == null){
            throw new InsufficientAuthenticationException("无效的token");
        }

        //根据用户id，构造出一个Authentication对象，给过滤器链中后面的Filter使用（过滤器链中处理的都是Authentication对象）
        UsernamePasswordAuthenticationToken usernamePasswordAuthenticationToken = new UsernamePasswordAuthenticationToken(wegoUserDetails,null,wegoUserDetails.getAuthorities());
        SecurityContextHolder.getContext().setAuthentication(usernamePasswordAuthenticationToken);
        //放行到过滤器链中的下一个过滤器过滤
        filterChain.doFilter(httpServletRequest,httpServletResponse);
    }

}
